﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Diagnostics;
using Microsoft.Win32;
using System.IO;
using DockingLibrary;
using RoughJsConsole;

namespace JsEditor
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public static String Filter = "JavaScript 文件(*.js)|*.js|Xml文件(*.xml)|*.xml|所有文件 |*.*";
        private DebugWindow debugWindow = new DebugWindow();

        internal static RecentFiles files = new RecentFiles();
        public MainWindow()
        {
            PresentationTraceSources.DataBindingSource.Listeners.Add(new ConsoleTraceListener());
            PresentationTraceSources.DataBindingSource.Switch.Level = SourceLevels.Error;
            //dockManager.
            InitializeComponent();
            this.KeyDown += new KeyEventHandler(MainWindow_KeyDown);
        }

        void MainWindow_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyStates == Keyboard.GetKeyStates(Key.S) && Keyboard.Modifiers == ModifierKeys.Control)
            {
                Save(false);
                e.Handled = true;
            }
            else if (e.KeyStates == Keyboard.GetKeyStates(Key.O) && Keyboard.Modifiers == ModifierKeys.Control)
            {
                OpenFile();
                e.Handled = true;
            }
            else if (e.KeyStates == Keyboard.GetKeyStates(Key.N) && Keyboard.Modifiers == ModifierKeys.Control)
            {
                NewFile();
                e.Handled = true;
            }
            else if (e.KeyStates == Keyboard.GetKeyStates(Key.S) && Keyboard.Modifiers == ModifierKeys.Control && Keyboard.Modifiers == ModifierKeys.Shift)
            {
                SaveAll();
                e.Handled = true;
            }
            else if (e.Key == Key.F5)
            {
                RunScript1();
                e.Handled = true;
            }


        }
        private void SaveAll()
        {
            for (int i = 0; i < files.Count; i++)
            {
                RecentFile recentFile = files[i];
                if (recentFile.Edit)
                {
                    DocumentContent doc = GetDocumentByTile(recentFile.FileName);
                    CommonSave(false, doc);
                }
            }
        }
        private DocumentContent GetDocumentByTile(String title)
        {
            foreach (DockingLibrary.DocumentContent doc in dockManager.Documents)
                if (string.Compare(doc.Title, title, true) == 0)
                    return doc;
            throw new Exception("[没有这样的文件]");
        }
        private bool ContainsDocument(string title)
        {
            foreach (DockingLibrary.DocumentContent doc in dockManager.Documents)
                if (string.Compare(doc.Title, title, true) == 0)
                    return true;
            return false;
        }
        private void NewDocument(object sender, RoutedEventArgs e)
        {
            NewFile();
        }

        private void NewFile()
        {
            string title = "scrpt";
            int i = 1;
            String path = "PATH_" + title;


            while (ContainsDocument(title + i.ToString() + "*.js"))
                i++;
            title = title + i.ToString() + "*.js";
            AddScriptFile(title, path, "", i, true);
        }

        private void AddScriptFile(string title, string path, String script, int i, bool edit)
        {
            DocWindow doc = new DocWindow(script);
            doc.DockManager = dockManager;
            doc.Title = title;

            ////doc.doc += new EventHandler(doc_Closed);
            doc.Show();
            doc.Parser.EditEvent += new EditEventDelegate(Parser_EditEvent);
            files.Add(new RecentFile(doc.Title, path, doc.Title.Length * i, edit));
        }

        void doc_DocClosed(object sender, TitleArgs args)
        {
            RecentFile recentFile = GetRecentFileByTitle(args.Title);
            files.Remove(recentFile);
        }



        void Parser_EditEvent(object sender, EventArgs args)
        {
            DocWindow doc = sender as DocWindow;
            if (doc != null)
            {
                RecentFile recentFile = GetRecentFileByTitle(doc.Title);
                ChangeEdit(recentFile);
            }
        }
        private void ChangeEdit(RecentFile recentFile)
        {
            if (!recentFile.Edit)
            {
                recentFile.Edit = true;
                String fileName = System.IO.Path.GetFileNameWithoutExtension(recentFile.FileName);
                String extName = System.IO.Path.GetExtension(recentFile.FileName);
                recentFile.FileName = fileName + "*" + extName;
                DocumentContent doc = dockManager.ActiveDocument;
                doc.Title = recentFile.FileName;
                dockManager.RefreshTitle();
            }
        }

        private void ExitApplication(object sender, RoutedEventArgs e)
        {
            Application.Current.Shutdown();
        }

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            dockManager.ParentWindow = this;
            dockManager.GetDocumentsPane().DocClosed += new ClosedEvent(doc_DocClosed);//当某个文档被关闭
            //dockManager.
            debugWindow.DockManager = dockManager;//输出窗口

            debugWindow.Show(Dock.Bottom);
            debugWindow.InitConsole();
        }

        private void OnClosing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            //Application.Current.st
            //Properties.Settings.Default.DockingLayoutState = dockManager.GetLayoutAsXml();
            //Properties.Settings.Default.Save();
        }

        private void ShowOutputWindow(object sender, RoutedEventArgs e)
        {
            debugWindow.Show();

        }


        private void RunScript(object sender, RoutedEventArgs e)
        {
            RunScript1();
        }

        private void RunScript1()
        {
            DocumentContent doc = dockManager.ActiveDocument;
            if (doc == null)
                return;
            String title = doc.Title;
            if (title == null || title.Trim() == "")
                return;
            if (doc.Title.Contains("*"))
            {
                Save(false);
                doc = dockManager.ActiveDocument;
                title = doc.Title;
            }
            
            RecentFile recentFile = GetRecentFileByTitle(title);
            this.debugWindow.RunFile(System.IO.Path.GetFullPath(recentFile.Path).Replace("\\", "/"));
        }

        private void SaveAsDocument(object sender, RoutedEventArgs e)
        {
            Save(true);
        }

        private void SaveDocument(object sender, RoutedEventArgs e)
        {

            Save(false);
        }

        private void SaveFile(RecentFile recentFile, DocumentContent doc)
        {
            DocWindow docWindow = doc as DocWindow;
            String script = docWindow.Text;
            using (StreamWriter writer = new StreamWriter(recentFile.Path, false, Encoding.Unicode))
            {

                try
                {
                    writer.Write(script);

                    String fileName = System.IO.Path.GetFileNameWithoutExtension(recentFile.FileName);
                    String safeName = fileName.Substring(0, fileName.Length - 1);
                    String extName = System.IO.Path.GetExtension(recentFile.FileName);
                    fileName = safeName + extName;


                    doc.Title = fileName;
                    dockManager.RefreshTitle(doc);

                    recentFile.FileName = fileName;

                    recentFile.Edit = false;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString(), "保存失败");
                }
                finally
                {
                    try
                    {
                        writer.Close();
                    }
                    catch { }
                }
            }
        }


        private void Save(bool isSaveAs)
        {
            DocumentContent doc = dockManager.ActiveDocument;
            if (doc == null)
                return;
            CommonSave(isSaveAs, doc);

        }

        private void CommonSave(bool isSaveAs, DocumentContent doc)
        {
            String title = doc.Title;
            if (title == null || title.Trim() == "")
                return;
            RecentFile recentFile = GetRecentFileByTitle(title);
            //直接保存
            bool isExist = false;
            //把文件名处理好，然后判断
            isExist = File.Exists(recentFile.Path);
            if (isExist && !isSaveAs)
            {
                if (recentFile.FileName.Contains("*"))
                    SaveFile(recentFile, doc);
                return;
            }

            //需要打开对话框保存
            SaveFileDialog dialog = new SaveFileDialog();
            dialog.Title = "保存";
            dialog.Filter = Filter;

            dialog.DefaultExt = "js";//默认扩展名
            dialog.AddExtension = true;//是否自动添加扩展名
            dialog.OverwritePrompt = true;//文件已存在是否提示覆盖
            dialog.CheckPathExists = true;//提示输入的文件名无效


            bool? result = dialog.ShowDialog(this);
            if (result != null && result == true)
            {
                //得到新的文件名，得到路径，修改文档中的名字，修改当前文件的名字,修改当前文件的编辑属性
                String fileName = dialog.FileName;
                String safeName = dialog.SafeFileName;
                DocWindow docWindow = doc as DocWindow;
                String script = docWindow.Text;
                Stream stream = dialog.OpenFile();
                using (StreamWriter writer = new StreamWriter(stream,Encoding.Unicode))
                {

                    try
                    {
                        writer.Write(script);
                        doc.Title = safeName;
                        dockManager.RefreshTitle(doc);

                        recentFile.FileName = safeName;
                        recentFile.Path = fileName;
                        recentFile.Edit = false;
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.ToString(), "保存失败");
                    }
                    finally
                    {
                        try
                        {
                            writer.Close();
                        }
                        catch { }
                    }
                }

            }
        }

        private RecentFile GetRecentFileByTitle(String title)
        {
            foreach (RecentFile f in files)
            {
                if (f.FileName == title)
                    return f;
            }
            throw new Exception("[没有打开这个文件:" + title + "]");
        }

        private void SaveAllDocument(object sender, RoutedEventArgs e)
        {
            SaveAll();
        }

        private void OpenDocument(object sender, RoutedEventArgs e)
        {
            OpenFile();
        }// end for method

        private void OpenFile()
        {
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.Multiselect = true;
            dialog.Title = "打开文件";
            dialog.Filter = Filter;
            bool? resultCom = dialog.ShowDialog(this);
            if (resultCom != null)
            {
                if (resultCom == true)
                {
                    String[] fileNames = dialog.FileNames;
                    String[] fileSafeNames = dialog.SafeFileNames;
                    Stream[] readers = dialog.OpenFiles();
                    for (int i = 0; i < fileNames.Length; i++)
                    {
                        using (StreamReader reader = new StreamReader(readers[i]))
                        {
                            try
                            {
                                String script = reader.ReadToEnd();
                                String fileName = fileNames[i];
                                String fileNameSafe = fileSafeNames[i];
                                //File.
                                // new Pat
                                AddScriptFile(fileNameSafe, fileName, script, i, false);
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show(ex.ToString(), "打开文件出错");
                            }
                            finally
                            {
                                try
                                {
                                    reader.Close();
                                }
                                catch { }
                            }
                        }

                    }// end for
                }
            }
        }

        private void ClearConsole(object sender, RoutedEventArgs e)
        {
            debugWindow.Clear();
        }

        private void ReStartConsole(object sender, RoutedEventArgs e)
        {
            debugWindow.ReStart();
        }

        private void MenuItem_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("功能还在扩展,有问题请与我联系\n天使坠 \nQQ:283440946 \nMSN:cxchen84xi@hotmail.com", "帮助");
        }
    }// end for class
}
